//
// Created by 86150 on 2021/10/14.
//
#ifndef BJUT_CPP3_CONTAINERS_H
#define BJUT_CPP3_CONTAINERS_H
double pi = 3.1415926;

class container
{
	protected:
		double radius;

	public:
		container(double r=0): radius(r) {}
		virtual double surface_area() = 0;
		virtual double volume() = 0;
};
class cube: public container
{
	public:
		cube(double r=0): container(r) {}
		double surface_area() override
		{
			return 6 * 4 * radius * radius;
		}
		double volume() override
		{
			return radius * radius * 8;
		}
		friend std::ostream& operator<< (std::ostream& cout, cube now)
		{
			cout<<"This is a cube, "
				<<"radius:"<<now.radius
				<<", surface_area: "<<now.surface_area()
				<<", volume: "<<now.volume()<<".\n";
			return cout;
		}
		friend void operator<< (std::string& str, cube now)
		{
			str = "surface area:" + std::to_string(now.surface_area()) + "\nvolume:" +
					std::to_string(now.volume()) + " .";
		}
};
class sphere: public container
{
	public:
		sphere(double r=0): container(r) {}
		double surface_area() override
		{
			return 4 * pi * radius * radius;
		}
		double volume() override
		{
			return (4 / 3) * pi * radius * radius * radius;
		}
		friend std::ostream& operator<< (std::ostream& cout, sphere now)
		{
			cout<<"This is a sphere, "
				<<"radius:"<<now.radius
				<<", surface_area: "<<now.surface_area()
				<<", volume: "<<now.volume()<<".\n";
			return cout;
		}
		friend void operator<< (std::string& str, sphere now)
		{
			str = "surface area:" + std::to_string(now.surface_area()) + "\nvolume:" +
					std::to_string(now.volume()) + ".";
		}
};

class cylinder: public container
{
	public:
		cylinder(double r=0): container(r) {}
		double surface_area() override
		{
			return 2 * pi * radius * radius + 2 * pi * radius * 2 * radius;
		}
		double volume() override
		{
			return pi * radius * radius * 2 * radius;
		}
		friend std::ostream& operator<< (std::ostream& cout, cylinder now)
		{
			cout<<"This is a cylinder, "
				<<"radius:"<<now.radius
				<<", surface_area: "<<now.surface_area()
				<<", volume: "<<now.volume()<<".\n";
			return cout;
		}
		friend void operator<< (std::string& str, cylinder now)
		{
			str = "surface area:" + std::to_string(now.surface_area()) + "\nvolume:" +
					std::to_string(now.volume()) + ".";
		}
};
#endif //BJUT_CPP3_CONTAINERS_H
